/*
 * Copyright (c) 2020 - present, Inspur Genersoft Co., Ltd.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/*
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.inspur.edp.cef.generator.repository.adaptor.method;

//import Inspur.Gsp.Caf.Generator.BaseInfoItem.*;
//import Inspur.Gsp.Caf.Generator.ClassMethodGenerator.*;
//import Inspur.Gsp.Caf.Generator.Utils.*;
//import Inspur.Gsp.Cef.Repository.Assembler.*;
//import Microsoft.CodeAnalysis.*;
//import Microsoft.CodeAnalysis.CSharp.*;
//import Microsoft.CodeAnalysis.CSharp.Syntax.*;

import com.inspur.edp.caf.generator.baseInfo.AnnotationInfo;
import com.inspur.edp.caf.generator.baseInfo.ParameterInfo;
import com.inspur.edp.caf.generator.baseInfo.TypeInfo;
import com.inspur.edp.caf.generator.method.ClassMethodGenerator;
import com.inspur.edp.cef.designtime.api.IFieldCollection;
import com.inspur.edp.cef.designtime.api.IGspCommonDataType;
import com.inspur.edp.cef.designtime.api.IGspCommonField;
import com.inspur.edp.cef.designtime.api.element.GspElementDataType;
import com.inspur.edp.cef.designtime.api.element.GspElementObjectType;
import com.inspur.edp.cef.designtime.api.util.Guid;
import com.inspur.edp.cef.generator.coreGenerator.base.CefCoreGenerator;
import com.inspur.edp.cef.generator.coreGenerator.base.CefCoreGeneratorContext;
import com.inspur.edp.cef.generator.repository.RepositoryGenUtil;
import com.inspur.edp.cef.repository.assembler.nesteddatatype.NestedColumnInfo;
import com.inspur.edp.cef.repository.assembler.nesteddatatype.NestedDataTypeAssembler;
import com.inspur.edp.udt.designtime.api.entity.ComplexDataTypeDef;
import com.inspur.edp.udt.designtime.api.entity.SimpleDataTypeDef;
import com.inspur.edp.udt.designtime.api.entity.element.ElementCollection;
import com.inspur.edp.udt.designtime.api.entity.element.UdtElement;
import com.inspur.edp.udt.designtime.api.entity.property.PropertyCollection;
import org.eclipse.jdt.core.dom.*;

import java.util.ArrayList;
import java.util.Map;

//protected abstract void initColumns();
public class NestedInitColumnGenerator extends ClassMethodGenerator {
	private IGspCommonDataType gspCommonDataType;
	private CefCoreGeneratorContext cefCoreGeneratorContext;
	public NestedInitColumnGenerator(CefCoreGeneratorContext cefCoreGeneratorContext, IGspCommonDataType gspCommonDataType) {
		this.cefCoreGeneratorContext = cefCoreGeneratorContext;
		this.gspCommonDataType = gspCommonDataType;
	}

	@Override
	protected Block buildMethodBody() {
		java.util.ArrayList<Statement> statements = new java.util.ArrayList<Statement>();
		IFieldCollection elementList = null;
		if(gspCommonDataType instanceof SimpleDataTypeDef){
			elementList = gspCommonDataType.getContainElements();
		}
		else if(gspCommonDataType instanceof ComplexDataTypeDef){
			elementList = getElements((ComplexDataTypeDef)gspCommonDataType);
		}
		for(IGspCommonField gspCommonField: elementList){
			if(gspCommonField.getIsVirtual())
				continue;
			Statement statement = buildAddColumnStatement(gspCommonField);
			statements.add(statement);
		}
		Block block = ast.newBlock();
		block.statements().addAll(statements);
		return block;
	}

	private IFieldCollection getElements(ComplexDataTypeDef dataType){
		switch (dataType.getDbInfo().getMappingType())
		{
			case SingleColumn:
				PropertyCollection properties = new PropertyCollection();
				dataType.initProperties(properties);
				ElementCollection tempVar = new ElementCollection();
				UdtElement udtElement=new UdtElement(properties);
				udtElement.setID(Guid.newGuid().toString());
				udtElement.setCode(dataType.getCode());
				udtElement.setName(dataType.getName());
				udtElement.setLabelID(dataType.getCode());
				udtElement.setObjectType(GspElementObjectType.None);
				udtElement.setMDataType(GspElementDataType.String);
				tempVar.add(udtElement);
				return tempVar;
			case MultiColumns:
				return dataType.getContainElements();
			default:
				throw new UnsupportedOperationException();
		}
	}

	private Statement buildAddColumnStatement(IGspCommonField field) {
		java.util.ArrayList arguments = buildArgumentList(field);
		String methodName = "addColumnInfo";
		SuperMethodInvocation methodInvocation = ast.newSuperMethodInvocation();
		methodInvocation.setName(ast.newSimpleName(methodName));
		methodInvocation.arguments().addAll(arguments);
		return ast.newExpressionStatement(methodInvocation);
	}

	private java.util.ArrayList buildArgumentList(IGspCommonField field) {
		java.util.ArrayList<Expression> argumentList = new java.util.ArrayList<Expression>();
		Expression propertyNameArgument = RepositoryGenUtil.getStringArgument(ast, field.getLabelID());
		argumentList.add(propertyNameArgument);

		ClassInstanceCreation createInstance = ast.newClassInstanceCreation();
		createInstance.setType(ast.newSimpleType(ast.newName(getProcessType(field.getLabelID()).getTypeName())));
		addImport(getProcessType(field.getLabelID()).getTypeFullName());
		argumentList.add(createInstance);

		Expression multiElementArgument = RepositoryGenUtil.getBoolArgumnet(ast, field.getIsMultiLanguage());
		argumentList.add(multiElementArgument);

		Expression udtElementArgument = RepositoryGenUtil.getBoolArgumnet(ast, field.getIsUdt());
		argumentList.add(udtElementArgument);

		Expression assElementArgument = RepositoryGenUtil.getBoolArgumnet(ast, field.getObjectType() == GspElementObjectType.Association);
		argumentList.add(assElementArgument);

		Expression enumElementArgument = RepositoryGenUtil.getBoolArgumnet(ast, field.getObjectType() == GspElementObjectType.Enum);
		argumentList.add(enumElementArgument);

		Expression belongEleArgument = RepositoryGenUtil.getStringArgument(ast, field == null ? "" : field.getLabelID());
		argumentList.add(belongEleArgument);

		return argumentList;
	}
	protected TypeInfo getProcessType(String columnName) {
		String className = columnName + "PersistanceValueReader";
		TypeInfo type =  new TypeInfo(className);
		type.setTypePackageName(cefCoreGeneratorContext.getCefGenContext().getApiGenContext().getPackageName());
		return type;
	}


	@Override
	protected ArrayList<Modifier.ModifierKeyword> getAccessModifiers() {
		return RepositoryGenUtil.createModifierKeywordArray(Modifier.ModifierKeyword.PROTECTED_KEYWORD);
	}

	@Override
	protected ArrayList<AnnotationInfo> getAttributeList() {
		return RepositoryGenUtil.buildOverrideAnnotationInfo(ast);
	}

	@Override
	protected String getMethodName() {
		return "initColumns";
	}

	@Override
	protected ArrayList<ParameterInfo> getParameterCollection() {
		return new java.util.ArrayList<ParameterInfo>();
	}

	@Override
	protected TypeInfo getReturnType() {
		return new TypeInfo(void.class);
	}
}
